<template>
    <div class="rogue-mouse-container">
        <canvas class="rogue-mouse-content" :width=canvasSize.width :height=canvasSize.height></canvas>
        <span style="position: fixed;left: 30%;top: 45%;font-size: 50px;">打开声音然后用鼠标在屏幕上摩擦</span>
    </div>
</template>

<script>
export default {
    name: "RogueMouse",
    components: {},
    data() {
        return {
            canvasCtx: null,
            canvasSize: {
                width: 0,
                height: 0,
            },
            CurX: 0,
            CurY: 0,
            oscillator: null,
            gainNode: null,
            maxFreq: 6000,
            maxVol: 1,
            initialFreq: 3000,
            initialVol: 0.5,
            stop:false,
        }
    },
    computed: {},
    methods: {
        random(number1, number2) {
            var randomNo =
                number1 + (Math.floor(Math.random() * (number2 - number1)) + 1);
            return randomNo;
        },
        canvasDraw() {
            if(this.stop){
                return;
            }
            const rX = this.CurX;
            const rY = this.CurY;
            const rC = Math.floor((this.gainNode.gain.value / this.maxVol) * 30);

            this.canvasCtx.globalAlpha = 0.2;

            for (var i = 1; i <= 15; i = i + 2) {
                this.canvasCtx.beginPath();
                this.canvasCtx.fillStyle =
                    "rgb(" +
                    100 +
                    i * 10 +
                    "," +
                    Math.floor((this.gainNode.gain.value / this.maxVol) * 255) +
                    "," +
                    Math.floor((this.oscillator.frequency.value / this.maxFreq) * 255) +
                    ")";
                this.canvasCtx.arc(
                    rX + this.random(0, 50),
                    rY + this.random(0, 50),
                    rC / 2 + i,
                    (Math.PI / 180) * 0,
                    (Math.PI / 180) * 360,
                    false,
                );
                this.canvasCtx.fill();
                this.canvasCtx.closePath();
            }
        },
        updatePage(e) {
            this.CurX = e.pageX;
            this.CurY = e.pageY;

            this.oscillator.frequency.value = (this.CurX / this.canvasSize.width) * this.maxFreq;
            this.gainNode.gain.value = (this.CurY / this.canvasSize.height) * this.maxVol;

            this.canvasDraw();
        },
    },
    mounted() {
        const container = this.$el;
        const canvas = this.$el.querySelector(".rogue-mouse-content");
        //初始化画布大小
        this.canvasSize.width = container.offsetWidth;
        this.canvasSize.height = container.offsetHeight;
        this.canvasCtx = canvas.getContext("2d");

        const AudioContext = window.AudioContext || window.webkitAudioContext;

        const audioCtx = new AudioContext();

        //音源
        this.oscillator = audioCtx.createOscillator();
        //音量控制
        this.gainNode = audioCtx.createGain();

        this.oscillator.connect(this.gainNode);
        this.gainNode.connect(audioCtx.destination);

        this.oscillator.type = "sine";
        this.oscillator.frequency.value = this.initialFreq;
        this.oscillator.start();

        this.gainNode.gain.value = this.initialVol;

        canvas.addEventListener("mousemove", this.updatePage);
    },
    beforeUnmount() {
        const canvas = this.$el.querySelector(".rogue-mouse-content");
        if(canvas){
            canvas.removeEventListener("mousemove", this.updatePage);
        }
        this.stop=true;
        if(this.oscillator){
            this.oscillator.stop();
            this.gainNode.disconnect();
        }
    }
}
</script>

<style scoped>
.rogue-mouse-container {
    width: 100%;
    height: 100%;
    display: flex;
    justify-content: center;
    align-items: center;
    position: relative;
}

</style>